package com.utsirc.irc;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.jibble.pircbot.IrcException;
import org.jibble.pircbot.NickAlreadyInUseException;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;

import com.utsirc.UTSirC;

public class IRCService extends Service {

	// keep a reference of messeger here, might still need it in case connection
	// unsuccessful
	private Messenger messenger;

	// reference to the irc client
	// most activities will be interfacing the irc client with the service
	public static IRCClient client;

	// create final binder variable
	// providing an access point to the current service object in activity
	private final IBinder myBinder = new LocalBinder();

	// keep track of this thread so
	public static IRCThread ircThread;

	@Override
	public IBinder onBind(Intent intent) {
		return myBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();
	}

	@SuppressLint("HandlerLeak")
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		this.messenger = new Messenger(UTSirC.instance.messageHandler);

		Bundle param = intent.getExtras();

		ircThread = new IRCThread();
		ircThread.setAddress(param.getString("ip"));
		ircThread.setNick(param.getString("nick"));

		// run irc client in a new thread
		// need to manage the thread's life cycle
		// leave it like this for now
		// since there's a possibility that the connection would fail
		ircThread.start();

		return super.onStartCommand(intent, flags, startId);
	}

	public class IRCThread extends Thread {

		// need it to continue running for some duration after that, use a
		// service
		public String address;
		public String nick;
		public int port = 6667;

		public void setAddress(String address) {
			this.address = address;
		}

		public void setNick(String nick) {
			this.nick = nick;
		}

		public void setPort(int port) {
			this.port = port;
		}

		public void run() {

			IRCService.client = new IRCClient(messenger);

			// attempt in establish connection to the irc server
			String ircConnectionError = null;
			try {
				IRCService.client.setNick(nick);
				IRCService.client.connect(address, port);

			} catch (NickAlreadyInUseException e) {
				ircConnectionError = "NICKINUSEEXCEPTION";
				e.printStackTrace();
			} catch (IOException e) {
				ircConnectionError = "IOEXCEPTION";
				e.printStackTrace();
			} catch (IrcException e) {
				ircConnectionError = "IRCEXCEPTION";
				e.printStackTrace();
			}

			// notify error if connection unsuccessful
			if (ircConnectionError != null) {
				try {
					notifyHandler(ircConnectionError,
							new HashMap<String, String>());
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		}
	}

	// notify the handler on irc state change
	private void notifyHandler(String message, Map<String, String> params)
			throws RemoteException {

		Bundle mBundle = new Bundle();
		for (Entry<String, String> param : params.entrySet()) {
			mBundle.putString(param.getKey(), param.getValue());
		}
		Message msg = Message.obtain();
		msg.obj = message;
		msg.setData(mBundle);
		this.messenger.send(msg);
	}

	class LocalBinder extends Binder {
		public IRCService getService() {
			return IRCService.this;
		}
	}
}